package com.isyscore.os.core.logger;

import com.isyscore.boot.logger.annotation.AccessLogger;
import com.isyscore.boot.logger.model.AccessLoggerInfo;
import com.isyscore.boot.logger.support.AccessLoggerSupport;
import com.isyscore.boot.logger.support.MethodInterceptorHolder;
import com.isyscore.boot.logger.util.AopUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @author felixu
 * @since 2021.11.17
 */
@Component
@ConditionalOnProperty(prefix = "isyscore.logger", value = "enabled", havingValue = "true")
public class OperationLoggerSupport extends AccessLoggerSupport {

    @Override
    protected AccessLoggerInfo createLogger(MethodInterceptorHolder holder) {
        OperationLogger logger = new OperationLogger();
        logger.setRequestTime(LocalDateTime.now());
        AccessLogger accessLogger = holder.findAnnotation(AccessLogger.class);
        ApiOperation apiOperation = holder.findAnnotation(ApiOperation.class);
        boolean useSelfAnn = apiOperation == null || !StringUtils.hasText(apiOperation.value());
        logger.setAction(useSelfAnn ? accessLogger == null ? "" : accessLogger.action() : apiOperation.value());
        logger.setDescribe(useSelfAnn ? accessLogger == null ? "" : accessLogger.describe() : apiOperation.notes());
        logger.setParameters(holder.getArgs());
        logger.setTarget(holder.getTarget().getClass());
        logger.setMethod(holder.getMethod());
        return logger;
    }

    @Override
    public boolean matches(@NonNull Method method, @NonNull Class<?> aClass) {
        AccessLogger ann = AopUtils.findAnnotation(aClass, method, AccessLogger.class);
        return ann != null ? !ann.ignore() : AopUtils.findAnnotation(aClass, method, RequestMapping.class) != null;
    }
}
